In [1]:
from ipysankeywidget import SankeyWidget
from ipywidgets import Layout

A convenience factory function


In [2]:
layout = Layout(width="300", height="200")
def sankey(margin_top=10, **value):
    """Show SankeyWidget with default values for size and margins"""
    return SankeyWidget(layout=layout,
                        margins=dict(top=margin_top, bottom=0, left=30, right=60),
                        **value)

Rank assignment

Rank sets

You can adjust the left-right placement of nodes by putting them in rank sets: all nodes in the same set end up with the same rank.


In [3]:
links = [
    {'source': 'A', 'target': 'B', 'value': 1},
    {'source': 'B', 'target': 'C', 'value': 1},
    {'source': 'A', 'target': 'D', 'value': 1},
]
sankey(links=links)



In [4]:
rank_sets = [
    { 'type': 'same', 'nodes': ['C', 'D'] }
]
sankey(links=links, rank_sets=rank_sets)



In [5]:
order = [
    ['A'],
    ['D', 'B'],
    ['C'],
]
sankey(links=links, order=order)



In [6]:
order = [
    [ [   ], ['A'], [],   ],
    [ ['B'], [   ], ['D'] ],
    [ [   ], ['C'], []    ],
]
sankey(links=links, order=order)


Reversed nodes

Most nodes are assumed to link from left to right, but sometimes there are return links which should be shown from right to left.


In [7]:
links = [
    {'source': 'A', 'target': 'B', 'value': 1},
    {'source': 'B', 'target': 'C', 'value': 1},
    {'source': 'C', 'target': 'D', 'value': 1},
    {'source': 'A', 'target': 'E', 'value': 0.5},
]

nodes = [
    {'id': 'C', 'direction': 'l'},
    {'id': 'D', 'direction': 'l'},
]

sankey(links=links, nodes=nodes)


Variations:


In [8]:
nodes = [
    {'id': 'C', 'direction': 'r'},
    {'id': 'D', 'direction': 'l'},
]
sankey(links=links, nodes=nodes)



In [9]:
nodes = [
    {'id': 'C', 'direction': 'l'},
    {'id': 'D', 'direction': 'r'},
]
sankey(links=links, nodes=nodes)


Styling

By default, the links are coloured according to their type:


In [10]:
links = [
    {'source': 'A', 'target': 'B', 'value': 3, 'type': 'x'},
    {'source': 'B', 'target': 'C', 'value': 2, 'type': 'y'},
    {'source': 'B', 'target': 'D', 'value': 1, 'type': 'z'},
]
sankey(links=links)


You can also set the colours directly:


In [11]:
links = [
    {'source': 'A', 'target': 'B', 'value': 3, 'color': 'steelblue'},
    {'source': 'B', 'target': 'C', 'value': 2, 'color': '#aaa'},
    {'source': 'B', 'target': 'D', 'value': 1, 'color': 'goldenrod'},
]
sankey(links=links)


Process titles default to their ids, but can be overridden. There are also one built-in alternative "style" of node:

  • process is drawn with a thicker line

In [12]:
nodes = [
    {'id': 'B', 'title': 'Middle node', 'style': 'process' },
]
sankey(links=links, nodes=nodes)


Of course, you can also use CSS to adjust the styling:


In [13]:
%%html
<style>
.sankey .node {
    font-style: italic;
}
</style>



In [14]:
links = [
    {'source': 'A1', 'target': 'B', 'value': 1.5, 'type': 'x'},
    {'source': 'A1', 'target': 'B', 'value': 0.5, 'type': 'y'},
    {'source': 'A2', 'target': 'B', 'value': 0.5, 'type': 'x'},
    {'source': 'A2', 'target': 'B', 'value': 1.5, 'type': 'y'},
    {'source': 'B',  'target': 'C', 'value': 2.0, 'type': 'x'},
    {'source': 'B',  'target': 'C', 'value': 2.0, 'type': 'y'},
]
sankey(links=links, nodes=[])



In [15]:
sankey(links=links, align_link_types=True)



In [16]:
order = [
    ['A2', 'A1'],
    ['B'],
    ['C'],
]
sankey(links=links, align_link_types=True, order=order)


Dynamic updating


In [17]:
from ipywidgets import Button, VBox

links = [
    {'source': 'A', 'target': 'B', 'value': 1},
    {'source': 'B', 'target': 'C', 'value': 1},
    {'source': 'A', 'target': 'D', 'value': 1},
]
order = [
    ['A'],
    ['D', 'B'],
    ['C'],
]
s = sankey(links=links, order=order)

def swap(x):
    global order
    order = [list(reversed(o)) for o in order]
    s.order = order
b = Button(description='Swap')
b.on_click(swap)

VBox([b, s])


Node groups


In [18]:
links = [
    {'source': 'A', 'target': 'B', 'value': 3, 'type': 'x'},
    {'source': 'B', 'target': 'C', 'value': 2, 'type': 'y'},
    {'source': 'B', 'target': 'D', 'value': 1, 'type': 'z'},
]
groups = [
    {'id': 'G', 'title': 'Group', 'nodes': ['C', 'D']}
]
sankey(links=links, nodes=[], groups=groups, margin_top=30)


Link labels show the numeric value of the link on the diagram:


In [19]:
sankey(links=links, linkLabelFormat='.1f')


By default the labels for small links are hidden, but you can customize this using linkLabelMinWidth:


In [20]:
links[2]['value'] = 0.1
links[1]['value'] = 2.9
sankey(links=links, linkLabelFormat='.1f')



In [21]:
sankey(links=links, linkLabelFormat='.1f', linkLabelMinWidth=4)



In [ ]:


In [ ]: